home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 126-150 / disk_147 / sys / bsd / bsd.zoo / ttyio.c < prev   
C/C++ Source or Header  |  1988-07-25  |  6KB  |  256 lines

  1. /*
  2.  *        Ultrix-32 and Unix terminal I/O.
  3.  * The functions in this file
  4.  * negotiate with the operating system for
  5.  * keyboard characters, and write characters to
  6.  * the display in a barely buffered fashion.
  7.  */
  8. #include    "def.h"
  9.  
  10. #include    <sgtty.h>
  11.  
  12. #define NOBUF    512            /* Output buffer size.        */
  13.  
  14. char    obuf[NOBUF];            /* Output buffer.        */
  15. int    nobuf;
  16. struct    sgttyb    oldtty;            /* V6/V7 stty data.        */
  17. struct    sgttyb    newtty;
  18. struct    tchars    oldtchars;        /* V7 editing.            */
  19. struct    tchars    newtchars;
  20. struct    ltchars oldltchars;        /* 4.2 BSD editing.        */
  21. struct    ltchars newltchars;
  22. #ifdef    TIOCGWINSZ
  23. struct    winsize winsize;        /* 4.3 BSD window sizing    */
  24. #endif
  25. int    nrow;                /* Terminal size, rows.        */
  26. int    ncol;                /* Terminal size, columns.    */
  27.  
  28. /*
  29.  * This function gets called once, to set up
  30.  * the terminal channel. On Ultrix is's tricky, since
  31.  * we want flow control, but we don't want any characters
  32.  * stolen to send signals. Use CBREAK mode, and set all
  33.  * characters but start and stop to 0xFF.
  34.  */
  35. ttopen() {
  36.     register char *tv_stype;
  37.     char *getenv(), *tgetstr(), tcbuf[1024], err_str[72];
  38.     char *sprintf();
  39.  
  40. /* do this the REAL way */
  41.     if ((tv_stype = getenv("TERM")) == NULL)
  42.     {
  43.         puts("Environment variable TERM not defined!");
  44.         exit(1);
  45.     }
  46.  
  47.     if((tgetent(tcbuf, tv_stype)) != 1)
  48.     {
  49.         (void) sprintf(err_str, "Unknown terminal type %s!", tv_stype);
  50.         puts(err_str);
  51.         exit(1);
  52.     }
  53.     if (ttraw() == FALSE)
  54.         panic("aborting due to terminal initialize failure");
  55. }
  56.  
  57. /*
  58.  * This function sets the terminal to RAW mode, as defined for the current
  59.  * shell.  This is called both by ttopen() above and by spawncli() to
  60.  * get the current terminal settings and then change them to what
  61.  * mg expects.    Thus, stty changes done while spawncli() is in effect
  62.  * will be reflected in mg.
  63.  */
  64. ttraw() {
  65.     extern short ospeed;
  66.  
  67.     if (ioctl(0, TIOCGETP, (char *) &oldtty) < 0) {
  68.         ewprintf("ttopen can't get sgtty");
  69.         return(FALSE);
  70.     }
  71.     newtty.sg_ospeed = ospeed = oldtty.sg_ospeed;
  72.     newtty.sg_ispeed = oldtty.sg_ispeed;
  73.     newtty.sg_erase     = oldtty.sg_erase;
  74.     newtty.sg_kill     = oldtty.sg_kill;
  75.     newtty.sg_flags     = oldtty.sg_flags;
  76.     newtty.sg_flags &= ~(ECHO|CRMOD);    /* Kill echo, CR=>NL.    */
  77. #ifdef FLOWCONTROL
  78.     newtty.sg_flags |= CBREAK;        /* Half-cooked mode.    */
  79. #else
  80.     newtty.sg_flags |= RAW|ANYP;        /* raw mode for 8 bit path.*/
  81. #endif
  82.     if (ioctl(0, TIOCSETP, (char *) &newtty) < 0) {
  83.         ewprintf("ttopen can't set sgtty");
  84.         return(FALSE);
  85.     }
  86.     if (ioctl(0, TIOCGETC, (char *) &oldtchars) < 0) {
  87.         ewprintf("ttopen can't get chars");
  88.         return(FALSE);
  89.     }
  90.     newtchars.t_intrc  = 0xFF;        /* Interrupt.        */
  91.     newtchars.t_quitc  = 0xFF;        /* Quit.        */
  92. #if FLOWCONTROL
  93.     newtchars.t_startc = 0x11;        /* ^Q, for terminal.    */
  94.     newtchars.t_stopc  = 0x13;        /* ^S, for terminal.    */
  95. #else
  96.     newtchars.t_startc = 0xFF;        /* ^Q, for terminal.    */
  97.     newtchars.t_stopc  = 0xFF;        /* ^S, for terminal.    */
  98. #endif
  99.     newtchars.t_eofc   = 0xFF;
  100.     newtchars.t_brkc   = 0xFF;
  101.     if (ioctl(0, TIOCSETC, (char *) &newtchars) < 0) {
  102.         ewprintf("ttraw can't set chars");
  103.         return(FALSE);
  104.     }
  105.     if (ioctl(0, TIOCGLTC, (char *) &oldltchars) < 0) {
  106.         panic("ttraw can't get ltchars");
  107.         return(FALSE);
  108.     }
  109.     newltchars.t_suspc  = 0xFF;        /* Suspend #1.        */
  110.     newltchars.t_dsuspc = 0xFF;        /* Suspend #2.        */
  111.     newltchars.t_rprntc = 0xFF;
  112.     newltchars.t_flushc = 0xFF;        /* Output flush.    */
  113.     newltchars.t_werasc = 0xFF;
  114.     newltchars.t_lnextc = 0xFF;        /* Literal next.    */
  115.     if (ioctl(0, TIOCSLTC, (char *) &newltchars) < 0) {
  116.         ewprintf("ttraw can't set ltchars");
  117.         return(FALSE);
  118.     }
  119.     setttysize() ;
  120.     return(TRUE);
  121. }
  122.  
  123. /*
  124.  * This function gets called just
  125.  * before we go back home to the shell. Put all of
  126.  * the terminal parameters back.
  127.  *    Under UN*X this just calls ttcooked(), but the ttclose() hook is in
  128.  * because vttidy() in display.c expects it for portability reasons.
  129.  */
  130. ttclose() {
  131.     if (ttcooked() == FALSE)
  132.         panic("");        /* ttcooked() already printf'd */
  133. }
  134.  
  135. /*
  136.  * This function restores all terminal settings to their default values,
  137.  * in anticipation of exiting or suspending the editor.
  138.  */
  139.  
  140. ttcooked() {
  141.     ttflush();
  142.     if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0) {
  143.         ewprintf("ttclose can't set ltchars");
  144.         return(FALSE);
  145.     }
  146.     if (ioctl(0, TIOCSETC, (char *) &oldtchars) < 0) {
  147.         ewprintf("ttclose can't set chars");
  148.         return(FALSE);
  149.     }
  150.     if (ioctl(0, TIOCSETP, (char *) &oldtty) < 0) {
  151.         ewprintf("ttclose can't set sgtty");
  152.         return(FALSE);
  153.     }
  154.     return(TRUE);
  155. }
  156.  
  157. /*
  158.  * Write character to the display.
  159.  * Characters are buffered up, to make things
  160.  * a little bit more efficient.
  161.  */
  162. ttputc(c)
  163. int c;
  164. {
  165.     if (nobuf >= NOBUF)
  166.         ttflush();
  167.     obuf[nobuf++] = c;
  168. }
  169.  
  170. /*
  171.  * Flush output.
  172.  */
  173. ttflush() {
  174.     if (nobuf != 0) {
  175.         if (write(1, obuf, nobuf) != nobuf)
  176.             panic("ttflush write failed");
  177.         nobuf = 0;
  178.     }
  179. }
  180.  
  181. /*
  182.  * Read character from terminal.
  183.  * All 8 bits are returned, so that you can use
  184.  * a multi-national terminal.
  185.  */
  186. ttgetc() {
  187.     char    buf[1];
  188.  
  189.     while (read(0, &buf[0], 1) != 1)
  190.         ;
  191.     return (buf[0] & 0xFF);
  192. }
  193. /*
  194.  * set the tty size. Functionized for 43BSD.
  195.  */
  196. setttysize() {
  197.  
  198. #ifdef    TIOCGWINSZ
  199.     if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
  200.         nrow = winsize . ws_row;
  201.         ncol = winsize . ws_col;
  202.     } else nrow = 0;
  203.     if(nrow<=0 || ncol<=0)
  204. #endif
  205.     if ((nrow=tgetnum ("li")) <= 0
  206.     || (ncol=tgetnum ("co")) <= 0) {
  207.         nrow = 24;
  208.         ncol = 80;
  209.     }
  210.     if (nrow > NROW)            /* Don't crash if the    */
  211.         nrow = NROW;            /* termcap entry is    */
  212.     if (ncol > NCOL)            /* too big.        */
  213.         ncol = NCOL;
  214. }
  215.  
  216. /*
  217.  * typeahead returns TRUE if there are characters available to be read
  218.  * in.
  219.  */
  220. typeahead() {
  221.     int    x;
  222.  
  223.     return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
  224. }
  225.  
  226. /*
  227.  * panic - just exit, as quickly as we can.
  228.  */
  229. panic(s) char *s; {
  230.     (void) fputs("panic: ", stderr);
  231.     (void) fputs(s, stderr);
  232.     (void) fputc('\n', stderr);
  233.     (void) fflush(stderr);
  234.     abort();        /* To leave a core image. */
  235. }
  236. #ifndef NO_DPROMPT
  237. #include <sys/time.h>
  238. /*
  239.  * A program to return TRUE if we wait for 2 seconds without anything
  240.  * happening, else return FALSE.  Cribbed from mod.sources xmodem.
  241.  */
  242. int ttwait() {
  243.     int readfd;
  244.     struct timeval tmout;
  245.  
  246.     tmout.tv_sec = 2;
  247.     tmout.tv_usec = 0;
  248.  
  249.     readfd = 1;
  250.  
  251.     if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
  252.         return(TRUE);
  253.     return(FALSE);
  254. }
  255. #endif
  256.